﻿#include "QlyAVCodec.h"

QlyAVCodec::QlyAVCodec()
{

}


QlyAVCodec::~QlyAVCodec()
{

}

QDebug operator<<(QDebug dbg, QlyAVCodec codec)
{
    switch (codec.mediaType()) {
    case AVMEDIA_TYPE_UNKNOWN:
        dbg.nospace() << "UNKNOWN TYPE";
        break;
    case AVMEDIA_TYPE_VIDEO:
        dbg.nospace() <<  "VIDEO";
        break;
    case AVMEDIA_TYPE_AUDIO:
        dbg.nospace() <<  "AUDIO";
        break;
    case AVMEDIA_TYPE_DATA:
        dbg.nospace() <<  "DATA";
        break;
    case AVMEDIA_TYPE_SUBTITLE:
        dbg.nospace() <<  "SUBTITLE";
        break;
    case AVMEDIA_TYPE_ATTACHMENT:
        dbg.nospace() <<  "ATTACHMENT";
        break;
    default:
        break;
    }
    dbg.nospace() << ", Codec id: " << codec.id()
                  << ", Codec name: " << codec.name()
                  << ", long name = " << codec.longName();

    return dbg.maybeSpace();
}

QlyAVCodec::QlyAVCodec(const AVCodec *codec)
{
    pCodec = codec;
}

bool QlyAVCodec::isSupportedPixelFormat(AVPixelFormat format) const
{
    QVector<AVPixelFormat> set = supportedPixelFormat();
    return set.contains(format);
}

bool operator == (AVRational r1, AVRational r2)
{
    return r1.den * r2.num == r1.num * r2.den;
}

bool QlyAVCodec::isSupportedFrameRate(AVRational rate) const
{
    QVector<AVRational> set = supportedFrameRate();
    return set.contains(rate);
}

bool QlyAVCodec::isSupportedSampleRate(int rate) const
{
    QVector<int> set = supportedSampleRate();
    return set.contains(rate);
}

QVector<AVPixelFormat> QlyAVCodec::supportedPixelFormat() const
{
    QVector<AVPixelFormat> format;
    if(pCodec)
    {
        const enum AVPixelFormat * pFormat = pCodec->pix_fmts;
        if(pFormat)
        {
            while (*pFormat != AV_PIX_FMT_NONE)
            {
                format << *pFormat;
                pFormat ++;
            }
        }
    }
    return format;
}

QVector<AVRational> QlyAVCodec::supportedFrameRate()const
{
    QVector<AVRational> frameRate;
    if(pCodec)
    {
        const AVRational * rate = pCodec->supported_framerates;
        if(rate)
        {
            while (rate->den != 0 && rate->num != 0)
            {
                frameRate << *rate;
                rate ++;
            }
        }

    }
    return frameRate;
}

QVector<int> QlyAVCodec::supportedSampleRate() const
{
    QVector<int> sampleRate;
    if(pCodec)
    {
        const int * rate = pCodec->supported_samplerates;
        if(rate)
        {
            while(*rate != 0)
            {
                sampleRate.push_back(*rate);
                rate ++;
            }
        }
    }
    return sampleRate;
}

QVector<QlyAVCodec> QlyAVCodec::allAVCodec()
{
    QVector<QlyAVCodec> v;

    void * state = nullptr;
    const AVCodec * p = av_codec_iterate(&state);
    while(p)
    {
        v.push_back(QlyAVCodec(p));
        p = av_codec_iterate(&state);
    }
    return v;
}

AVMediaType QlyAVCodec::mediaType() const
{
    if(pCodec == nullptr) return AVMEDIA_TYPE_UNKNOWN;
    return pCodec->type;
}

enum AVCodecID QlyAVCodec::id() const
{
    if(pCodec == nullptr) return AV_CODEC_ID_NONE;
    return pCodec->id;
}

QString QlyAVCodec::name() const
{
    if(pCodec == nullptr) return QString();
    return QString(pCodec->name);
}

QString QlyAVCodec::longName() const
{
    if(pCodec == nullptr) return QString();
    return QString(pCodec->long_name);
}

bool QlyAVCodec::findDecoder(QString name)
{
    pCodec = avcodec_find_decoder_by_name(name.toLocal8Bit().constData());
    return pCodec;
}

bool QlyAVCodec::isEncoder()
{
    return av_codec_is_encoder(pCodec);
}

bool QlyAVCodec::isDecoder()
{
    return av_codec_is_decoder(pCodec);
}

bool QlyAVCodec::findEncoder(QString name)
{
    pCodec = avcodec_find_encoder_by_name(name.toLocal8Bit().constData());
    return pCodec;
}

bool QlyAVCodec::findEncoder(enum AVCodecID id)
{
    pCodec = avcodec_find_encoder(id);
    return pCodec;
}

bool QlyAVCodec::findDecoder(AVCodecID id)
{
    pCodec = avcodec_find_decoder(id);
    return pCodec;
}
